#include "JniUtils.h"

#include <map>
#include <string>

using namespace std;

static ImageDataFieldID _ImageDataFieldID("com/seetaface2/model/SeetaImageData");
static RectFieldID _RectFieldID("com/seetaface2/model/SeetaRect");
static PointFieldID _PointFieldID("com/seetaface2/model/SeetaPointF");
static RecognizeFieldID _RecognizeFieldID("com/seetaface2/model/RecognizeResult");

JniUtils::JniUtils()
{
}


JniUtils::~JniUtils()
{
}

/*
 * 将java的SeetaImageData对象转成C++的SeetaImageData 
 */
SeetaImageData JniUtils::toSeetaImageData(JNIEnv *env, jobject jimg){
	ImageDataFieldID field = getImageDataFieldID(env);

	//获取人脸图片数据，转为SeetaImageData对象
	SeetaImageData imgdata;
	jbyteArray jbytes = (jbyteArray)env->GetObjectField(jimg, field.data);
	imgdata.data = (unsigned char*)env->GetByteArrayElements(jbytes, 0);
	imgdata.width = env->GetIntField(jimg, field.width);
	imgdata.height = env->GetIntField(jimg, field.height);
	imgdata.channels = env->GetIntField(jimg, field.channels);
	//LOGD("img data: width=%i,height=%i,channels=%i\n", imgdata.width, imgdata.height, imgdata.channels);
	//删除局部引用
	env->DeleteLocalRef(jbytes);
	return imgdata;
}

/*
* 将java的SeetaRect[]对象转成C++的SeetaRect[]
*/
SeetaRect * JniUtils::toSeetaRectArray(JNIEnv *env, jobjectArray jfaces) {
	RectFieldID field = getRectFieldID(env);

	int face_num = env->GetArrayLength(jfaces);
	SeetaRect *faces = new SeetaRect[face_num];
	for (int i = 0; i < face_num; i++)
	{
		jobject jface = env->GetObjectArrayElement(jfaces, i);
		faces[i].x = env->GetIntField(jface, field.x);
		faces[i].y = env->GetIntField(jface, field.y);
		faces[i].width = env->GetIntField(jface, field.width);
		faces[i].height = env->GetIntField(jface, field.height);

		//删除局部引用
		env->DeleteLocalRef(jface);
	}

	return faces;
}

ImageDataFieldID JniUtils::getImageDataFieldID(JNIEnv *env) {
	//printf("\nget SeetaImageDataFieldID...\n");
	if (!_ImageDataFieldID.init) {
		//printf("init SeetaImageDataFieldID...\n");
		//获取SeetaImageData java对象
		jclass clazz = env->FindClass(_ImageDataFieldID.className);
		//获取SeetaImageData对象的属性
		_ImageDataFieldID.data = env->GetFieldID(clazz, "data", "[B");
		_ImageDataFieldID.width = env->GetFieldID(clazz, "width", "I");
		_ImageDataFieldID.height = env->GetFieldID(clazz, "height", "I");
		_ImageDataFieldID.channels = env->GetFieldID(clazz, "channels", "I");

		//初始化完成
		_ImageDataFieldID.init = true;
	}
	return _ImageDataFieldID;
}

RectFieldID JniUtils::getRectFieldID(JNIEnv *env) {
	//printf("get RectFieldID...\n");
	if (!_RectFieldID.init) {
		//printf("init RectFieldID...\n");
		//获取SeetaRect java对象
		jclass clazz = env->FindClass(_RectFieldID.className);
		//获取默认构造方法
		_RectFieldID.constructor = env->GetMethodID(clazz, "<init>", "()V");
		//获取SeetaRect对象的属性
		_RectFieldID.x = env->GetFieldID(clazz, "x", "I");
		_RectFieldID.y = env->GetFieldID(clazz, "y", "I");
		_RectFieldID.width = env->GetFieldID(clazz, "width", "I");
		_RectFieldID.height = env->GetFieldID(clazz, "height", "I");

		//初始化完成
		_RectFieldID.init = true;
	}
	return _RectFieldID;
}

PointFieldID JniUtils::getPointFieldID(JNIEnv *env) {
	//printf("get PointFieldID...\n");
	if (!_PointFieldID.init) {
		//printf("init PointFieldID...\n");
		//获取SeetaPointF java对象
		jclass clazz = env->FindClass(_PointFieldID.className);
		//获取默认构造方法
		_PointFieldID.constructor = env->GetMethodID(clazz, "<init>", "()V");
		//获取SeetaPointF对象的属性
		_PointFieldID.x = env->GetFieldID(clazz, "x", "D");
		_PointFieldID.y = env->GetFieldID(clazz, "y", "D");

		//初始化完成
		_PointFieldID.init = true;
	}
	return _PointFieldID;
}

RecognizeFieldID JniUtils::getRecognizeFieldID(JNIEnv * env) {
	if (!_RecognizeFieldID.init) {
		//获取RecognizeResult java对象
		jclass clazz = env->FindClass(_RecognizeFieldID.className);
		//获取默认构造方法
		_RecognizeFieldID.constructor = env->GetMethodID(clazz, "<init>", "()V");
		//获取对象的属性
		_RecognizeFieldID.index = env->GetFieldID(clazz, "index", "I");
		_RecognizeFieldID.similar = env->GetFieldID(clazz, "similar", "F");

		//初始化完成
		_RecognizeFieldID.init = true;
	}
	return _RecognizeFieldID;
}

jobject JniUtils::newObject(JNIEnv * env, JClassDef classDef){
	jclass clazz = env->FindClass(classDef.className);
	return env->NewObject(clazz, classDef.constructor);
}
